package com.tutorial;

import java.io.IOException;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;

import org.apache.commons.collections.ListUtils;
import org.codehaus.jackson.map.ObjectMapper;

import bean.Grade;

import com.mongodb.BasicDBObject;
import com.mongodb.DB;
import com.mongodb.DBCollection;
import com.mongodb.DBCursor;
import com.mongodb.DBObject;
import com.mongodb.MongoClient;
import com.mongodb.ServerAddress;
import comparator.ScoreComparator;
import comparator.StudentComparator;

public class HelloWorldMongoDBStyle {

	public static void main(String[] args) throws UnknownHostException {
		
		DBCollection dbCollection = readData();
		
		//get distinct students
		List<Integer> distinctStudents = dbCollection.distinct("student_id");
		
		//get all grades
		DBCursor dbCursor = dbCollection.find();
		List<Grade> allGrades = getPojo(dbCursor);
		Collections.sort(allGrades, new StudentComparator());
		//System.out.println("Size of allGrades " + allGrades.size());
		
		// get lowest grades for homework
		List<Grade> lowestGrades = new ArrayList<Grade>();
		for (Integer studentId : distinctStudents) {
			DBObject query = new BasicDBObject("type", "homework").append("student_id", studentId);
			dbCursor = dbCollection.find(query);
			List<Grade> homeworkGrades = getPojo(dbCursor);
			Collections.sort(homeworkGrades, new ScoreComparator());
			lowestGrades.add(homeworkGrades.get(0));
		}
		Collections.sort(lowestGrades, new StudentComparator());
		//System.out.println("Size of lowestGrades " + lowestGrades.size());
		//print(lowestGrades);
		
		// remove lowest grades
		List<Grade> finalList = ListUtils.removeAll(allGrades, lowestGrades);
		//System.out.println("final Size " + finalList.size());
		print(finalList);
	}

	/**
	 * @param removeAll
	 */
	private static void print(List<Grade> removeAll) {
		Iterator<Grade> iterator = removeAll.iterator();
		while (iterator.hasNext()) {
			Grade grade = (Grade) iterator.next();
			System.out.println(grade);
		}
		System.out.println("");
	}

	private static List<Grade> getPojo(DBCursor dbCursor) {
		ObjectMapper mapper = new ObjectMapper();
		List<Grade> grades = new ArrayList<Grade>();
		while (dbCursor.hasNext()) {
			grades.add(convertToPojo(mapper, dbCursor.next()));
		}
		return grades;
	}

	/**
	 * @throws UnknownHostException
	 */
	private static DBCollection readData() throws UnknownHostException {
		MongoClient mongoClient = new MongoClient(new ServerAddress("localhost", 27017));
		DB database = mongoClient.getDB("students");
		return database.getCollection("grades");
	}
	
	private static Grade convertToPojo(ObjectMapper mapper, DBObject obj)
	{
		try {
			return mapper.readValue(obj.toString(), Grade.class);
		} catch (IOException e) {
			e.printStackTrace();
		}
		return null;
	}

}
